package netcode.helper;

import java.net.DatagramPacket;
import java.util.Arrays;

public class Message {
	private byte data[];
	private int currentIndex;
	private boolean hasNext;

	public Message(byte code) {
		data = new byte[] { NetcodeHelper.BRAINS_AND_BETS,
				NetcodeHelper.MESSAGE_VERSION, code };
		hasNext = false;
	}

	public Message(DatagramPacket packet) {
		if (packet.getData()[NetcodeHelper.BB_MESSAGE_ID_INDEX] == NetcodeHelper.BRAINS_AND_BETS) {
			if (packet.getData()[NetcodeHelper.BB_MESSAGE_VERSION_INDEX] == NetcodeHelper.MESSAGE_VERSION) {
				data = Arrays.copyOf(packet.getData(), packet.getLength());
			}
		}
		currentIndex = NetcodeHelper.DATA_OFFSET;
		if(data[currentIndex] == NetcodeHelper.END_OF_MESSAGE){
			hasNext = false;
		}else{
			hasNext = true;
		}
	}

	public void add(int value) {
		add(NetcodeHelper.intToByteArray(value));
		add(NetcodeHelper.END_OF_STRING);
	}

	public void add(String value) {
		add(value.getBytes());
		add(NetcodeHelper.END_OF_STRING);
	}

	private void add(byte value) {
		byte temp[] = new byte[] { value };
		data = catByteArray(data, temp);
	}

	private void add(byte value[]) {
		data = catByteArray(data, value);
	}

	private byte[] catByteArray(byte first[], byte second[]) {
		byte temp[] = new byte[first.length + second.length];
		for (int i = 0; i < first.length; i++) {
			temp[i] = first[i];
		}
		for (int i = 0; i < second.length; i++) {
			temp[i + first.length] = second[i];
		}
		return temp;
	}

	public byte[] getData() {
		return data;
	}

	public int getDataLength() {
		return data.length;
	}
	
	public byte getMessageType(){
		return data[NetcodeHelper.BB_MESSAGE_TYPE_INDEX];
	}

	public boolean hasNext() {
		return hasNext;
	}
	
	public String nextString() throws Exception{
		if(hasNext){
			String value = "";
			for (; data[currentIndex] != NetcodeHelper.END_OF_STRING && data[currentIndex] != NetcodeHelper.END_OF_MESSAGE; currentIndex++) {
				value += String.valueOf((char) data[currentIndex]);
			}
			if(data[currentIndex] == NetcodeHelper.END_OF_MESSAGE){
				hasNext = false;
			}else{
				currentIndex++;
			}
			
			return value;
			
		}else{
			throw new Exception("Tried to call nextString(), however, there is no more data.");
		}
	}
	
	public int nextInt() throws Exception{
		if(hasNext){
			byte value[] = Arrays.copyOfRange(data, currentIndex, currentIndex+4);
			currentIndex += 4;
			if(data[currentIndex] == NetcodeHelper.END_OF_MESSAGE){
				hasNext = false;
			}else{
				currentIndex++;
			}
			return NetcodeHelper.byteArrayToInt(value);
		}else{
			throw new Exception("Tried to call nextInt(), however, there is no more data.");
		}
	}
	
	public void finalize(){
		if(data.length > 3){
			data[data.length -1] = NetcodeHelper.END_OF_MESSAGE;
		}else{
			add(NetcodeHelper.END_OF_MESSAGE);
		}
	}
}
